using Core.SimpleTemp.Application.YH;
using Core.SimpleTemp.Common;
using Core.SimpleTemp.Common.AutoMapperExtend;
using Core.SimpleTemp.Common.BaseLibrary;
using Core.SimpleTemp.Common.PagingQuery;
using Core.SimpleTemp.Entitys;
using Core.SimpleTemp.Repositories;
using Core.Toolkit.Common;
using Core.Toolkit.Core;
using Core.Toolkit.Core.Api;
using Core.Toolkit.Core.Application;
using Core.Toolkit.Core.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Core.SimpleTemp.Application
{
    [AutoDi()]
    public class YH_OperationAndWorkService : YH_BaseService<YH_OperationAndWorkDto, YH_OperationAndWork, YH_OperationAndWorkRepository>
    {
        readonly ExcelHelp _excelHelp;
        readonly TempDirDiHelp _TempDirHelp;
        readonly IDataDicHelp _dataDicHelp;
        readonly IHttpContextAccessor _accessor;
        readonly UserIdentity _userIdentity;
        readonly SysAreaRepository _sysAreaRepository;
        readonly YHService _yHService;
        public YH_OperationAndWorkService(
            YH_OperationAndWorkRepository repository, ExcelHelp excelHelp,
            TempDirDiHelp tempDirHelp, IDataDicHelp dataDicHelp,
            IHttpContextAccessor accessor, SysAreaRepository sysAreaRepository,
            YHService yHService) : base(repository)
        {
            _excelHelp = excelHelp;
            _TempDirHelp = tempDirHelp;
            _dataDicHelp = dataDicHelp;
            _accessor = accessor;
            _userIdentity = accessor?.HttpContext?.User?.GetUserIdentity();
            _sysAreaRepository = sysAreaRepository;
            _yHService = yHService;
        }



        public override LoadPageOffsetModel<YH_OperationAndWork, YH_OperationAndWorkDto>
            GetLoadPageOffsetMode(PagingModel<YH_OperationAndWorkDto>
                pagingQueryModel)
        {
            var dtoModel = pagingQueryModel.Model;
            var AreaIds = dtoModel.AreaIds;
            var loadPageOffsetModel = this.GetLoadPageOffsetModel(pagingQueryModel);
            var baseQuery = _repository.QueryBase().AsNoTracking();
            #region 查询条件
            var filterList = this.CreateQRList()
                         .Add("AreaID", "=") //区域ID
            .Add("JobSteps", "=") //作业步骤
            .Add("Task", "=") //作业任务
            .Add("RiskLevel", "=") //隐患等级ID
            .Add("CheckStandard", "in") //检查标准
            .Add("RiskOfViolation", "in"); //违反标准的风险
            //工厂处理
            if (_userIdentity.Headoffice)
                filterList.Add("CreateFactory", "="); //总部从查询条件取工厂id
            else
                filterList.Add("CreateFactory", "=", _userIdentity.Factory);
            var filterExpre = filterList.BuildeQR(dtoModel.ToEntity<YH_OperationAndWork>());
            //区域处理
            if (AreaIds != null && AreaIds.Any())
            {
                //filterExpre = filterExpre.And(a => AreaIds.Contains(a.AreaID.Value));
                filterExpre = filterExpre != null ? filterExpre.And(a => AreaIds.Contains(a.AreaID.Value)) : a => AreaIds.Contains(a.AreaID.Value);
            }
            loadPageOffsetModel.QueryWhere = filterExpre;
            #endregion

            loadPageOffsetModel.BasqQuery = baseQuery;
            loadPageOffsetModel.Order = orderModel => orderModel.CreateTime;
            loadPageOffsetModel.Selector = model => new YH_OperationAndWork()
            {
                Id = model.Id,
                AreaID = model.AreaID,//区域ID
                JobSteps = model.JobSteps,//作业步骤
                Task = model.Task,//作业任务
                RiskLevel = model.RiskLevel,//隐患等级ID
                CheckStandard = model.CheckStandard,//检查标准
                RiskOfViolation = model.RiskOfViolation,//违反标准的风险
                CreateFactory = model.CreateFactory,//隶属工厂
                CreateDept = model.CreateDept,//添加部门
                UpdateDept = model.UpdateDept,//更改部门
            };
            return loadPageOffsetModel;
        }


        public async Task<IPageModel<YH_OperationAndWorkDto>> GetList(PagingModel<YH_OperationAndWorkDto>
            pagingQueryModel)
        {
            var loadPageOffsetModel = GetLoadPageOffsetMode(pagingQueryModel);
            return await base.LoadPageOffsetAsync(loadPageOffsetModel);
        }


        public async Task<string> Export(PagingModel<YH_OperationAndWorkDto> pagingQueryModel)
        {
            const string FILE_NAME_PREFIX = "排查标准_操作与相关作业活动";
            var loadPageOffsetModel = GetLoadPageOffsetMode(pagingQueryModel);
            var DataList = await this.ExportDataAsync(loadPageOffsetModel);
            Guid userFactory = (Guid)_userIdentity.Factory;
            var sysAreas = await _yHService.GetAreaByFactoryAsync();
            var excelData = DataList.Select(model => new
            {

                model.JobSteps,
                JobSteps_title = "作业步骤",
                model.Task,
                Task_title = "作业任务",
                model.CheckStandard,
                CheckStandard_title = "检查标准",
                model.RiskOfViolation,
                RiskOfViolation_title = "违反标准的风险",
                model.RiskLevelText,
                RiskLevelText_title = "隐患等级",
                //model.CreateFactory,
                //CreateFactory_title = "隶属工厂",
                //model.CreateDept,
                //CreateDept_title = "添加部门",
                //model.UpdateDept,
                //UpdateDept_title = "更改部门",
                Area = sysAreas.Where(a => a.Id == model.AreaID).FirstOrDefault()?.Name,
                Area_title = "区域",
            }).ToList();

            var fileName = FILE_NAME_PREFIX + TempDirHelp.GetTimeStampFielName(".xlsx");
            return _excelHelp.Create(excelData, fileName);
        }


        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public async Task<List<string>> ImportAsync(IFormFile file)
        {
            //当前用户工厂ID
            Guid userFactory = (Guid)_userIdentity.Factory;
            var extension = System.IO.Path.GetExtension(file.FileName);
            var filePath = _TempDirHelp.GetFilePath(extension);
            await Filehelp.WriteFileAsync(file.OpenReadStream(), filePath);
            var dataList = new List<YH_OperationAndWork>();
            var errMsgList = new List<string>();
            var sysAreas = await _yHService.GetAreaByFactoryAsync();

            IWorkbook workbook = new XSSFWorkbook(filePath);
            try
            {
                var sheet = workbook.GetSheetAt(0);
                int rowCount = sheet.LastRowNum;
                //验证模板是否正确
                var first = sheet.GetRow(0);
                if (first.GetCell(0)?.ToString() != "作业步骤" ||
                    first.GetCell(1)?.ToString() != "作业任务" ||
                    first.GetCell(2)?.ToString() != "检查标准" ||
                    first.GetCell(3)?.ToString() != "违反标准的风险" || first.GetCell(4)?.ToString() != "隐患等级")
                {
                    errMsgList.Add($"请确认模板是否正确!");
                }
                for (int i = 1; i <= rowCount; i++)
                {
                    var row = sheet.GetRow(i);
                    var entity = new YH_OperationAndWork();



                    //0.操作步骤与作业工序 
                    if (string.IsNullOrWhiteSpace(row.GetCell(0)?.ToString()))
                        errMsgList.Add($"第{i}行，【作业步骤】列 不能为空！");
                    else
                        entity.JobSteps = row.GetCell(0)?.ToString();

                    //1.操作行为与作业任务 
                    if (string.IsNullOrWhiteSpace(row.GetCell(1)?.ToString()))
                        //errMsgList.Add($"第{i}行，【作业任务】列 不能为空！");
                        entity.Task = "";
                    else
                        entity.Task = row.GetCell(1)?.ToString();

                    //2.排查标准 
                    if (string.IsNullOrWhiteSpace(row.GetCell(2)?.ToString()))
                        errMsgList.Add($"第{i}行，【检查标准】列 不能为空！");
                    //entity.CheckStandard = "";
                    else
                        entity.CheckStandard = row.GetCell(2)?.ToString();

                    //3.违反标准生成的风险 
                    if (string.IsNullOrWhiteSpace(row.GetCell(3)?.ToString()))
                        errMsgList.Add($"第{i}行，【违反标准的风险】列 不能为空！");
                    //entity.RiskOfViolation = "";
                    else
                        entity.RiskOfViolation = row.GetCell(3)?.ToString();

                    var riskLevelId = _yHService.GetRiskLevelId(row.GetCell(4).ToString());
                    //4.隐患等级
                    if (riskLevelId == Guid.Empty)
                        errMsgList.Add($"第{i}行，【隐患等级】列 数据异常");

                    else
                    {
                        entity.RiskLevel = riskLevelId;
                    }

                    entity.CreateFactory = userFactory;
                    //区域
                    if (string.IsNullOrWhiteSpace(row.GetCell(5)?.ToString()))
                        errMsgList.Add($"第{i}行，【区域】列 不能为空！");
                    else
                    {
                        var factoryName = row.GetCell(5)?.ToString();
                        var sysarea = _yHService.FindAreaOfAreaListAsync(sysAreas, factoryName);
                        if (sysarea == null)
                            errMsgList.Add($"第{i}行，【区域】列 区域名是否正确！");
                        entity.AreaID = sysarea.Id;
                    }

                    dataList.Add(entity);
                }
            }
            catch (Exception ex)
            {
                //errMsgList.Add($"导入异常:" + ex.Message);
            }
            finally
            {
                workbook.Close();
            }
            if (errMsgList.Any())
                return errMsgList;
            await _repository.Set.AddRangeAsync(dataList);
            await _repository.SaveAsync();
            System.IO.File.Delete(filePath);
            return errMsgList;
        }



    }

}
